package main

import (
	"fmt"
	. "go_data_structures_and_algorithms/system_class/section11/pojo"
)

func main() {
	var tree = Node{
		Val: 1,
		Childrens: []Node{
			{
				Val: 2,
				Childrens: []Node{
					{Val: 5},
					{Val: 6},
					{Val: 7},
				},
			},
			{
				Val: 3,
				Childrens: []Node{
					{Val: 8},
					{Val: 9},
				},
			},
			{
				Val: 4,
				Childrens: []Node{
					{Val: 10},
				},
			},
		},
	}
	code := EnCode(&tree)
	li := CengJiBianLi(code)
	fmt.Println(li)
	node := decode(code)
	code1 := EnCode(node)
	li1 := CengJiBianLi(code1)
	fmt.Println(li1)

}

// 1.先建立根节点把所有孩子节点放在根节点的左边界上深度遍历到最左边的节点
func EnCode(root *Node) *BinaryTree {
	if root == nil {
		return nil
	}
	head := NewBinaryTree(root.Val)
	head.Left = en(root.Childrens)
	return head
}

func en(childrens []Node) *BinaryTree {
	if childrens == nil || len(childrens) == 0 {
		return nil
	}
	var head *BinaryTree //head就是最左边的头节点往后所有的儿子都挂在他的右边
	var cur *BinaryTree  //记录右边挂到哪个节点的指针

	for _, children := range childrens {
		tNode := NewBinaryTree(children.Val)

		if head == nil { //如果头没初始化就初始化
			head = tNode
		} else {
			cur.Right = tNode //头初始化好的情况下让其挂到右节点上
		}
		cur = tNode                       //移动到下一个节点
		cur.Left = en(children.Childrens) //递归遍历寻找节点的子节点组成二叉树后将头节点挂载到当前节点的左边
	}
	return head
}

func decode(node *BinaryTree) *Node {
	if node == nil {
		return nil
	}

	return NewNode(node.Value, *de(node.Left))
}

func de(head *BinaryTree) *[]Node {

	nodes := []Node{}

	for head != nil { //head就相当于孩子节点的最左边的节点是整个孩子节点的头节点所以要遍历这个头节点然后在判断他是否有对应的子节点
		cur := NewNode(head.Value, *de(head.Left)) //如果有左孩子就优先进入这个递归函数进行深层遍历
		head = head.Right                          //往右孩子遍历
		nodes = append(nodes, *cur)                //把对应的多叉树节点加入到孩子数组中
	}
	return &nodes //最终将所有的孩子数组返回
}
